package com.zyy.game.tianlong.callback;

import com.zyy.game.tianlong.network.GameContext;
import com.zyy.game.tianlong.network.callback.GlobalExceptionCallBack;
import com.zyy.game.tianlong.network.exception.ThreadRejectedException;
import io.netty.handler.codec.EncoderException;
import io.netty.util.concurrent.EventExecutorGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author relufi
 * @date 2019/7/29 0029
 */
@Slf4j
@Component
public class GlobalExceptionCallBackImpl implements GlobalExceptionCallBack {
    private final EventExecutorGroup eventExecutors;

    public GlobalExceptionCallBackImpl(EventExecutorGroup eventExecutors) {
        this.eventExecutors = eventExecutors;
    }

    @Override
    public void exceptionCaught(GameContext ctx, Throwable cause) {
        //客户端强制断开
        if (cause instanceof IOException) {
            log.debug("客户端强制断开 -- 此处做一些掉线处理");

//            示例： 使用业务线程池执行耗时任务，不要直接执行,会阻塞Work线程
            eventExecutors.execute(() -> log.debug("耗时任务"));
        } else if (cause instanceof EncoderException) {
            log.debug("解析错误，客户端发送的协议错误");
        }
        // 业务线程任务队列满了溢出(如果队列设置为最大就不需要考虑了)
        else if (cause instanceof ThreadRejectedException) {
            // 这里发送信息并立刻关闭流 或者 使用排队进入的方法 (此处业务线程池任务已满，就不要使用业务线程池了，或者使用新的线程)
//            ctx.writeFlushAndClose(new SocketMsg(0, 0, JSON.toJSONString(new TestMsg("对不起，服务器人数爆满请稍后再来"))));
            log.error("任务队列问题", cause);
        } else {
            log.error("其他异常", cause);
        }
    }
}
